home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / dev / gg / ncurses-5.3.lha / ncurses-5.3 / form / fty_regex.c < prev    next >
C/C++ Source or Header  |  2002-10-24  |  7KB  |  259 lines

  1.  
  2. /*
  3.  * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.
  4.  * You may freely copy it for use as a template for your own field types.
  5.  * If you develop a field type that might be of general use, please send
  6.  * it back to the ncurses maintainers for inclusion in the next version.
  7.  */
  8. /***************************************************************************
  9. *                                                                          *
  10. *  Author : Juergen Pfeifer                                                *
  11. *  Contact: http://www.familiepfeifer.de/Contact.aspx?Lang=en              *
  12. *                                                                          *
  13. ***************************************************************************/
  14.  
  15. #include "form.priv.h"
  16.  
  17. MODULE_ID("$Id: fty_regex.c,v 1.16 2002/07/06 15:33:27 juergen Exp $")
  18.  
  19. #if HAVE_REGEX_H_FUNCS    /* We prefer POSIX regex */
  20. #include <regex.h>
  21.  
  22. typedef struct
  23. {
  24.   regex_t *pRegExp;
  25.   unsigned long *refCount;
  26. } RegExp_Arg;
  27.  
  28. #elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
  29. #undef RETURN
  30. static int reg_errno;
  31.  
  32. static char *RegEx_Init(char *instring)
  33. {
  34.     reg_errno = 0;
  35.     return instring;
  36. }
  37.  
  38. static char *RegEx_Error(int code)
  39. {
  40.     reg_errno = code;
  41.     return 0;
  42. }
  43.  
  44. #define INIT         register char *sp = RegEx_Init(instring);
  45. #define GETC()        (*sp++)
  46. #define PEEKC()        (*sp)
  47. #define UNGETC(c)    (--sp)
  48. #define RETURN(c)    return(c)
  49. #define ERROR(c)    return RegEx_Error(c)
  50.  
  51. #if HAVE_REGEXP_H_FUNCS
  52. #include <regexp.h>
  53. #else
  54. #include <regexpr.h>
  55. #endif
  56.  
  57. typedef struct
  58. {
  59.   char *compiled_expression;
  60.   unsigned long *refCount;
  61. } RegExp_Arg;
  62.  
  63. /* Maximum Length we allow for a compiled regular expression */
  64. #define MAX_RX_LEN   (2048)
  65. #define RX_INCREMENT (256)
  66.  
  67. #endif
  68.  
  69. /*---------------------------------------------------------------------------
  70. |   Facility      :  libnform
  71. |   Function      :  static void *Make_RegularExpression_Type(va_list * ap)
  72. |
  73. |   Description   :  Allocate structure for regex type argument.
  74. |
  75. |   Return Values :  Pointer to argument structure or NULL on error
  76. +--------------------------------------------------------------------------*/
  77. static void *Make_RegularExpression_Type(va_list * ap)
  78. {
  79. #if HAVE_REGEX_H_FUNCS
  80.   char *rx = va_arg(*ap,char *);
  81.   RegExp_Arg *preg;
  82.  
  83.   preg = (RegExp_Arg*)malloc(sizeof(RegExp_Arg));
  84.   if (preg)
  85.     {
  86.       if (((preg->pRegExp = (regex_t*)malloc(sizeof(regex_t))) != (regex_t*)0)
  87.        && !regcomp(preg->pRegExp,rx,
  88.            (REG_EXTENDED | REG_NOSUB | REG_NEWLINE) ))
  89.     {
  90.       preg->refCount = (unsigned long *)malloc(sizeof(unsigned long));
  91.       *(preg->refCount) = 1;
  92.     }
  93.       else
  94.     {
  95.       if (preg->pRegExp)
  96.         free(preg->pRegExp);
  97.       free(preg);
  98.       preg = (RegExp_Arg*)0;
  99.     }
  100.     }
  101.   return((void *)preg);
  102. #elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
  103.   char *rx = va_arg(*ap,char *);
  104.   RegExp_Arg *pArg;
  105.  
  106.   pArg = (RegExp_Arg *)malloc(sizeof(RegExp_Arg));
  107.  
  108.   if (pArg)
  109.     {
  110.       int blen = RX_INCREMENT;
  111.       pArg->compiled_expression = NULL;
  112.       pArg->refCount = (unsigned long *)malloc(sizeof(unsigned long));
  113.       *(pArg->refCount) = 1;
  114.  
  115.       do {
  116.     char *buf = (char *)malloc(blen);
  117.     if (buf)
  118.       {
  119. #if HAVE_REGEXP_H_FUNCS
  120.         char *last_pos = compile (rx, buf, &buf[blen], '\0');
  121. #else /* HAVE_REGEXPR_H_FUNCS */
  122.         char *last_pos = compile (rx, buf, &buf[blen]);
  123. #endif
  124.         if (reg_errno)
  125.           {
  126.         free(buf);
  127.         if (reg_errno==50)
  128.           blen += RX_INCREMENT;
  129.         else
  130.           {
  131.             free(pArg);
  132.             pArg = NULL;
  133.             break;
  134.           }
  135.           }
  136.         else
  137.           {
  138.         pArg->compiled_expression = buf;
  139.         break;
  140.           }
  141.       }
  142.       } while( blen <= MAX_RX_LEN );
  143.     }
  144.   if (pArg && !pArg->compiled_expression)
  145.     {
  146.       free(pArg);
  147.       pArg = NULL;
  148.     }
  149.   return (void *)pArg;
  150. #else
  151.   return 0;
  152. #endif
  153. }
  154.  
  155. /*---------------------------------------------------------------------------
  156. |   Facility      :  libnform
  157. |   Function      :  static void *Copy_RegularExpression_Type(
  158. |                                      const void * argp)
  159. |
  160. |   Description   :  Copy structure for regex type argument.
  161. |
  162. |   Return Values :  Pointer to argument structure or NULL on error.
  163. +--------------------------------------------------------------------------*/
  164. static void *Copy_RegularExpression_Type(const void * argp)
  165. {
  166. #if (HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS)
  167.   const RegExp_Arg *ap = (const RegExp_Arg *)argp;
  168.   const RegExp_Arg *result = (const RegExp_Arg *)0;
  169.  
  170.   if (ap)
  171.     {
  172.       *(ap->refCount) += 1;
  173.       result = ap;
  174.     }
  175.   return (void *)result;
  176. #else
  177.   return 0;
  178. #endif
  179. }
  180.  
  181. /*---------------------------------------------------------------------------
  182. |   Facility      :  libnform
  183. |   Function      :  static void Free_RegularExpression_Type(void * argp)
  184. |
  185. |   Description   :  Free structure for regex type argument.
  186. |
  187. |   Return Values :  -
  188. +--------------------------------------------------------------------------*/
  189. static void Free_RegularExpression_Type(void * argp)
  190. {
  191. #if HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
  192.   RegExp_Arg *ap = (RegExp_Arg *)argp;
  193.   if (ap)
  194.     {
  195.       if (--(*(ap->refCount)) == 0)
  196.     {
  197. #if HAVE_REGEX_H_FUNCS
  198.       if (ap->pRegExp)
  199.         {
  200.           free(ap->refCount);
  201.           regfree(ap->pRegExp);
  202.         }
  203. #elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
  204.       if (ap->compiled_expression)
  205.         {
  206.           free(ap->refCount);
  207.           free(ap->compiled_expression);
  208.         }
  209. #endif
  210.       free(ap);
  211.     }
  212.     }
  213. #endif
  214. }
  215.  
  216. /*---------------------------------------------------------------------------
  217. |   Facility      :  libnform
  218. |   Function      :  static bool Check_RegularExpression_Field(
  219. |                                      FIELD * field,
  220. |                                      const void  * argp)
  221. |
  222. |   Description   :  Validate buffer content to be a valid regular expression
  223. |
  224. |   Return Values :  TRUE  - field is valid
  225. |                    FALSE - field is invalid
  226. +--------------------------------------------------------------------------*/
  227. static bool Check_RegularExpression_Field(FIELD * field, const void  * argp)
  228. {
  229.   bool match = FALSE;
  230. #if HAVE_REGEX_H_FUNCS
  231.   const RegExp_Arg *ap = (const RegExp_Arg*)argp;
  232.   if (ap && ap->pRegExp)
  233.     match = (regexec(ap->pRegExp,field_buffer(field,0),0,NULL,0) ? FALSE:TRUE);
  234. #elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
  235.   RegExp_Arg *ap = (RegExp_Arg *)argp;
  236.   if (ap && ap->compiled_expression)
  237.     match = (step(field_buffer(field,0),ap->compiled_expression) ? TRUE:FALSE);
  238. #endif
  239.   return match;
  240. }
  241.  
  242. static FIELDTYPE typeREGEXP = {
  243.   _HAS_ARGS | _RESIDENT,
  244.   1,                           /* this is mutable, so we can't be const */
  245.   (FIELDTYPE *)0,
  246.   (FIELDTYPE *)0,
  247.   Make_RegularExpression_Type,
  248.   Copy_RegularExpression_Type,
  249.   Free_RegularExpression_Type,
  250.   Check_RegularExpression_Field,
  251.   NULL,
  252.   NULL,
  253.   NULL
  254. };
  255.  
  256. NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_REGEXP = &typeREGEXP;
  257.  
  258. /* fty_regex.c ends here */
  259.